Javascript DOM编程艺术读书笔记8

第8章 充实文档的内容

两项重要原则:

  1. 渐进增强:应该总是从最核心的部分,也就是从内容开始逐步加强
  2. 平稳退化:缺乏必要的CSS和JS支持的访问者也可以访问到核心内容

充实文档的基本思路
用JS函数先把文档结构里的一些现有信息提取出来,再把哪些信息以一种清晰和有意义的方式插入到文档中去。比如下面编写的几个函数:

  • displayAbbreviations.js:把文档里的缩略语显示为一个“缩略语”列表
  • displayCitations.js:把文档里引用的每段文献节选生成一个“文献来源链接”
  • displsyAccesskeys.js:把一个元素与键盘上的某个特定按键关联在一起

1
2
3
4
5
6
7
8
9
10
├─explanation.html

├─scripts
│ addLoadEvent.js
│ displayAbbreviations.js
│ displayCitations.js
│ displsyAccesskeys.js

└─styles
typography.css

explanation.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Explaining the Document Object Model</title>
<link rel="stylesheet" type="text/css" media="screen" href="styles/typography.css"/>
<script type="text/javascript" src="scripts/addLoadEvent.js"></script>
<script type="text/javascript" src="scripts/displayAbbreviations.js"></script>
<script type="text/javascript" src="scripts/displayCitations.js"></script>
<script type="text/javascript" src="scripts/displsyAccesskeys.js"></script>
</head>
<body>
<ul id="navigation">
<li><a href="index.html" accesskey="1">Home</a></li>
<li><a href="search.html" accesskey="4">Search</a></li>
<li><a href="contact.html" accesskey="0">Contact</a></li>
</ul>
<h1>What is the Document Object Model?</h1>
<p>
The <abbr title="World Wide Web Consortium">W3C</abbr> defines
the <abbr title="Document Object Model">DOM</abbr> as:
</p>
<blockquote cite="http://www.w3.org/DOM/">
<p>
A platform- and language-neutral interface that will allow programs
and scripts to dynamically access and update the
content, structure and style of documents.
</p>
</blockquote>
<p>
It is an <abbr title="Application Programming Interface">API</abbr>
that can be used to navigate <abbr title="HyperText Markup Language">
HTML</abbr> and <abbr title="eXtensible Markup Language">XML
</abbr> documents.
</p>
</body>
</html>

addLoadEvent.js

1
2
3
4
5
6
7
8
9
10
11
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}

displayAbbreviations.js:把文档里的缩略语显示为一个“缩略语”列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function displayAbbreviations() {
if (!document.getElementsByTagName || !document.createElement || !document.createTextNode) return false;
//取得所有缩略词
var abbrevistions = document.getElementsByTagName("abbr");
//判断是否有abbr元素
if (abbrevistions.length < 1) return false;
var defs = new Array();
//遍历这些缩略词
for (var i = 0; i < abbrevistions.length; i++) {
var current_abbr = abbrevistions[i];
//在IE浏览器中的平稳退化,如果当前元素没有子节点,就会立刻开始下一次循环。因为IE浏览器在统计abbr元素的子节点的个数时总会返回一个错误的值0.
if(current_abbr.childNodes.length<1)continue;
var definition = current_abbr.getAttribute("title");
//文本节点是元素内部的第一个也是最后一个节点,即唯一节点
var key = current_abbr.lastChild.nodeValue;
defs[key] = definition;
}
//创建定义列表
var dlist = document.createElement("dl");
//遍历定义
for (key in defs) {
var definition = defs[key];
//创建定义标题
var dtitle = document.createElement("dt");
var dtitle_text = document.createTextNode(key);
dtitle.appendChild(dtitle_text);
//创建定义描述
var ddesc = document.createElement("dd");
var ddesc_text = document.createTextNode(definition);
ddesc.appendChild(ddesc_text);
//把他们添加到定义列表
dlist.appendChild(dtitle);
dlist.appendChild(ddesc);
}
//ie浏览器的defs数组是空的,就不会创建出任何dt和dd元素,如果dl没有任何子节点,就立刻退出该函数
if(dlist.childNodes.length<1) return false;
//创建标题
var header = document.createElement("h2");
var header_text = document.createTextNode("Abbreviations");
header.appendChild(header_text);
//把标题添加到页面主体
document.body.appendChild(header);
//把定义列表添加到页面主体
document.body.appendChild(dlist);
}
addLoadEvent(displayAbbreviations);

displayCitations.js:把文档里引用的每段文献节选生成一个“文献来源链接”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function displayCitations(){
if(!document.getElementsByTagName||!document.createElement||!document.createTextNode) return false;
//取得所有的引用
var quotes=document.getElementsByTagName("blockquote");
//遍历引用
for(var i=0;i<quotes.length;i++){
//如果该节点没有cite属性,就立刻跳到下一个循环
if(!quotes[i].getAttribute("cite")){
continue;
}
//保存cite属性
var url=quotes[i].getAttribute("cite");
//取得引用中的所有元素节点的固定用法,不能直接quites[i].lastChild因为最后一个子节点可能是换行符之类,而不是最后一个元素节点
var quoteChildren=quotes[i].getElementsByTagName('*');
//如果没有元素节点,就继续循环
if(quoteChildren.length<1)continue;
//取得引用中的最后一个元素节点
var elem=quoteChildren[quoteChildren.length-1];
//创建标记
var link=document.createElement("a");
var link_text=document.createTextNode("source");
link.appendChild(link_text);
link.setAttribute("href",url);
var superscript=document.createElement("sup");
superscript.appendChild(link);
//把标记添加到引用中的最后一个元素节点
elem.appendChild(superscript);
}
}
addLoadEvent(displayCitations);

displsyAccesskeys.js:把一个元素与键盘上的某个特定按键关联在一起

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

function displayAccesskeys(){
if(!document.getElementsByTagName||!document.createElement||!document.createTextNode)return false;
//取得文档中的所有链接
var links=document.getElementsByTagName("a");
//创建一个数组,保存访问键
var akeys=new Array();
//遍历链接
for(var i=0;i<links.length;i++){
var current_link=links[i];
//如果没有accesskey属性,就继续下一个循环
if(!current_link.getAttribute("accesskey"))continue;
//取得accesskey的值
var key=current_link.getAttribute("accesskey");
//取得链接文本
var text=current_link.lastChild.nodeValue;
//添加到数组
akeys[key]=text;
}
//创建列表
var list=document.createElement("ul");
//遍历访问键
for(key in akeys){
var text=akeys[key];
//创建放到列表项中的字符串
var str=key+":"+text;
//创建列表项
var item=document.createElement("li");
var item_text=document.createTextNode(str);
item.appendChild(item_text);
//把列表项添加到列表中
list.appendChild(item);
}
//创建标题
var header=document.createElement("h3");
var header_text=document.createTextNode("Accesskeys");
header.appendChild(header_text);
//把标题添加到页面主体
document.body.appendChild(header);
//把列表添加到页面主体
document.body.appendChild(list);
}
addLoadEvent(displayAccesskeys);

typography.css

1
2
3
4
5
6
7
8
9
body {
font-family: "Helvetica","Arial",sans-serif;
font-size: 10pt;
}
abbr {
text-decoration: none;
border: 0;
font-style: normal;
}